package lyricguess.models;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

public class Server {

	public final int ROUNDS_PER_SONG = 6;
	public final long TIME_PER_ROUND = 5000;
	public final long TIME_JOIN_WINDOW = 5000;

	//Hashmap of <Id, Player>
	private HashMap<UUID, Player> players = new HashMap<UUID, Player>();

	public void Run()
	{		
		while (true)
		{
			//NewSong (10 seconds window to join)
			SendToClients(new Object[] {"NewSong"}); //Notify users
			long joinStartTime = System.currentTimeMillis(); 
			while (System.currentTimeMillis() - joinStartTime < TIME_JOIN_WINDOW)
			{
				Object[] result = ReceiveNewPlayer();
				String name = (String) result[0];
				Boolean isObserver = (Boolean) result[1];

				//Generate id
				UUID newID = UUID.randomUUID();
				//Add player
				players.put(newID, new Player(name, isObserver));

				//Modify existing players
			}

			//LyricsSent (1 minute: Send some name and lyrics)	
			String name; //Retrieve name from database
			String lyrics; //Retrieve lyrics from database
			SendToClients(new Object[]{"LyricsSent", name, lyrics});

			android.os.SystemClock.sleep(60000);

			//Loop for preset number of rounds
			for (int roundIndex = 1; roundIndex <= ROUNDS_PER_SONG; roundIndex++)
			{
				//NewRound (5 seconds)
				String phraseMissing; //Retrieve lyrics with missing phrase
				String predictions;	//Retrieve predictions
				int correctPredictionIndex = 0; //Retrieve index of correct prediction

				//Send phrase with missing lyrics and send predictions (to guess from)
				SendToClients(new Object[]{"NewRound", phraseMissing, predictions});								

				//Track round start time
				long roundStartTime = System.currentTimeMillis(); 

				//Round variables
				UUID winnerId = null; 
				ArrayList<UUID> guessedPlayerIds = new ArrayList<UUID>();
				while (System.currentTimeMillis() - roundStartTime < TIME_PER_ROUND)
				{					
					//Get next guess
					Object[] result = ReceiveGuess();
					UUID id = (UUID) result[0];
					int guessIndex = (Integer) result[1];

					//check if player exists
					if (players.containsKey(id))
					{
						//Check if this is player's first guess
						if (!guessedPlayerIds.contains(id))
						{
							guessedPlayerIds.add(id);
							if (guessIndex == correctPredictionIndex)
							{
								//Set the winner id
								winnerId = id;
								break;
							}
						}
					}
				}

				//Update scores
				if (winnerId != null)
				{
					players.get(winnerId).score += 1;
				}

				//Send scores to players
				SendToClients(new Object[] {"EndRound", players.values().toArray(), winnerId});
			}

			//EndSong
			//Send final scores
			SendToClients(new Object[] {"EndSong", players.values().toArray()});
		}
	}

	public void SendToClients(Object[] commands)
	{
		//Server-side team implements this

		//For now, just print
		for (Object command : commands)
		{
			System.out.println(command);
		}
	}

	//Receive next guess, from buffer or what not
	public Object[] ReceiveGuess()
	{
		int guessIndex = 5;
		UUID id = UUID.fromString("1234");
		//Server-side team implements this
		return new Object[] {id, guessIndex};
	}

	//Receive next guess, from buffer or what not
	public Object[] ReceiveNewPlayer()
	{
		String name = "Ivan";
		boolean isObserver = false;
		//Server-side team implements this
		return new Object[] {name, isObserver};
	}
}
